package com.herui.iot.ui.evaluation.execute;

import android.util.Log;

import com.herui.device_lib.listener.DeviceLis;
import com.herui.device_lib.presenter.DevicePresenterInter;
import com.herui.device_lib.presenter.SimDevicePresenter;
import com.herui.device_lib.treadmill.SimTreadmillManager;
import com.herui.device_lib.treadmill.TreadmillManager;
import com.herui.device_lib.treadmill.TreadmillMsgFactory;
import com.herui.device_lib.treadmill.TreadmillWebsocketManager;
import com.herui.device_lib.treadmill.tp.MessageType;
import com.herui.device_lib.treadmill.tp.TreadmillMsg;
import com.herui.device_lib.treadmill.tp.body.CommandBody;
import com.herui.device_lib.treadmill.tp.body.CommandID;
import com.herui.device_lib.treadmill.tp.body.EcgBody;
import com.herui.device_lib.treadmill.tp.body.HeartRateDataBody;
import com.herui.device_lib.treadmill.tp.body.StageBody;
import com.herui.device_lib.treadmill.tp.body.StageType;
import com.herui.device_lib.treadmill.tp.body.TreadmillDataBody;
import com.herui.device_lib.treadmill.tp.body.UserInfoBody;
import com.herui.sdyu_lib.http.callback.Callback;
import com.herui.sdyu_lib.utils.ToastUtil;
import com.herui.sport_care.BaseView;
import com.herui.sport_care.config.AppConfig;
import com.herui.sport_care.config.ServerConfig;
import com.herui.sport_care.data.RepositoryFactory;
import com.herui.sport_care.data.check.AgreementDetailResponse;
import com.herui.sport_care.data.check.AgreementResponse;
import com.herui.sport_care.data.check.EvaluationStage;
import com.herui.sport_care.data.eval.EvalInfo;
import com.herui.sport_care.data.user.UserInfo;
import com.herui.sport_care.data.user.source.UserSource;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Created by amanda.shan on 2022/12/11.
 * 跑台车
 */
public class TreadmillExecutePresenter extends BaseExecutePresenter {

    static String TAG = "TreadmillExecutePresenter";

    public static interface View extends BaseView, DeviceLis,
            TreadmillWebsocketManager.TreadmillDataLis {
        // 回调阶段名称
        default void onStage(EvaluationStage stage) {
        }

        // 回调经过的时间
        default void onTime(int second) {
        }

        //回调协议
        default void onAgreementResponse(AgreementResponse agreementResponse) {
        }

        // 完成所有
        default void finish() {
        }
    }

    private ExecutorService executorService = Executors.newSingleThreadExecutor();

    // 协议详细信息
    private AgreementResponse agreementResponse;

    private TreadmillManager treadmillManager;
    private View view;
    private Timer timer;
    private Long startTime;     // 小阶段的开始时间
    private List<AgreementDetailResponse> agreementDetailList;  // 每个阶段的控制流程
    private int index;  // 阶段序号

    public TreadmillExecutePresenter(View view, EvalInfo evalInfo) {
        super(evalInfo);
        this.view = view;

    }

    @Override
    public void start() {
        super.start();
        getAgreement(evalInfo.getAgreementId());
        timer = new Timer();
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                if (stage != null && agreementDetailList != null && index < agreementDetailList.size()) {
                    int d = (int) ((System.currentTimeMillis() - startTime) / 1000);
                    AgreementDetailResponse agreementDetailResponse =
                            agreementDetailList.get(index);
                    // 发送新的阻力
                    if (d >= agreementDetailResponse.getDuration()) {
                        agreementDetailResponse = agreementDetailList.get(index++);
                        // 坡度 速度
                        Double gradient = agreementDetailResponse.getGradient();
                        Double velocity = agreementDetailResponse.getVelocity();
                        treadmillManager.sendSpeedAndSlop(gradient, velocity);
                        startTime = System.currentTimeMillis();
                    }
                }

                if (stage != null) {
                    view.onTime((int) ((System.currentTimeMillis() - stageStartTime) / 1000));
                }

                // 恢复阶段
                if (stage != null && stage.equals(EvaluationStage.RECOVER)) {
                    recoverProcess();
//                    recoverDataUp(false);
                }
            }
        }, 0, 1000);
    }

    public void stop() {
        super.stop();
        timer.cancel();
        if (treadmillManager != null){
            treadmillManager.close();
        }
    }

    // 下一步
    public void next() {
        UserSource userSource = RepositoryFactory.getInstance().getUserSource();
        UserInfo userInfo = userSource.getUserInfo();
        if (treadmillManager == null){
            try {
                URI uri = new URI(ServerConfig.getWebsocketUrl()+userInfo.getId());
                if (AppConfig.DeviceDebug){
                    treadmillManager = new SimTreadmillManager(treadmillDataLis);
                }else {
                    treadmillManager = new TreadmillWebsocketManager(treadmillDataLis, uri);
                }
            } catch (URISyntaxException e) {
                e.printStackTrace();
                Log.e(TAG, "next: 连接websoket失败");
                ToastUtil.showMessage("连接websoket失败");
                return;
            }
        }

        executorService.execute(new Runnable() {
            @Override
            public void run() {

                // 判断是否进行下一步
                if (agreementDetailList != null && index < agreementDetailList.size()) {
                    ToastUtil.showMessage("当前阶段还未完成无法下一步");
                    return;
                }

                if (agreementDetailList != null && index >= agreementDetailList.size()
                        && startTime != null && agreementDetailList.size() > 0) {
                    AgreementDetailResponse agreementDetailResponse =
                            agreementDetailList.get(agreementDetailList.size() - 1);
                    int d = (int) ((System.currentTimeMillis() - startTime) / 1000);
                    if (agreementDetailResponse.getDuration()==null){
                        Log.d(TAG, "next: 当前阶段没有设置持续时长");
                    }
                    else if (d < agreementDetailResponse.getDuration()) {
                        ToastUtil.showMessage("当前阶段还未完成无法下一步");
                        return;
                    }
                }

                if (stage == null) {
                    TreadmillMsgFactory.baseInit(userInfo.getId() + "",
                            treadmillDeviceInfo.getMac());
                    // 热身阶段
                    if (startWarmUp()) {
                        stageStartTime = System.currentTimeMillis();
                        agreementDetailList = agreementResponse.getWarmUpAgreementDetailList();
                        stage = EvaluationStage.WARM_UP;
                        view.onStage(stage);
                    }
                } else if (stage == EvaluationStage.WARM_UP) {
                    if (startTest()) {
                        stageStartTime = System.currentTimeMillis();
                        agreementDetailList = agreementResponse.getIncreaseAgreementDetailList();
                        stage = EvaluationStage.TESTING;
                        view.onStage(stage);
                    }
                } else if (stage == EvaluationStage.TESTING) {
                    if (startRecover()) {
                        stageStartTime = System.currentTimeMillis();
                        agreementDetailList = agreementResponse.getRecoverAgreementDetailList();
                        stage = EvaluationStage.RECOVER;
                        view.onStage(stage);
                    }
                } else if (stage == EvaluationStage.RECOVER) {
                    // 完成测试
                    treadmillManager.sendSpeedAndSlop(0.0, 0.0);
                    treadmillManager.close();
                    recoverDataUp(true);
                }

                startTime = System.currentTimeMillis();
                stageStartTime = System.currentTimeMillis();

                index = 0;
                // 发送阻力
                if (agreementDetailList.size() > 0) {
                    AgreementDetailResponse agreementDetailResponse =
                            agreementDetailList.get(index++);
                    // 坡度 速度
                    Double gradient = agreementDetailResponse.getGradient();
                    Double velocity = agreementDetailResponse.getVelocity();
                    treadmillManager.sendSpeedAndSlop(gradient, velocity);
                }

            }
        });
    }

    @Override
    protected void dataUploadSucess(Boolean uploadAll) {
        if (stage == EvaluationStage.RECOVER && uploadAll) {
            view.finish();
        }
    }

    /**
     * 开始热身
     * 跑步机一体机APP发送用户信息、心电设备地址及开始热身指令
     *
     * @return
     */
    private boolean startWarmUp() {

        UserInfo userInfo = RepositoryFactory.getInstance().getUserSource().getUserInfo();

        // 发送用户信息和心电设备地址
        // 用户信息 信息不够
        UserInfoBody userInfoBody = new UserInfoBody();
        userInfoBody.setUserId(evalUserInfo.getUserId().intValue());
        userInfoBody.setName(evalUserInfo.getName());
        userInfoBody.setOrganName(evalUserInfo.getOrganName());
        userInfoBody.setGender(evalUserInfo.getGender());
        userInfoBody.setMobile(evalUserInfo.getMobile());
        userInfoBody.setUserName(evalUserInfo.getUserName());
        userInfoBody.setHeadSculpture(evalUserInfo.getHeadSculpture());
        userInfoBody.setRandomNumber(evalUserInfo.getRandomNumber());
        userInfoBody.setEcgMac(ecgDeviceInfo.getMac().replace(":", ""));

        userInfoBody.setBetaSchemeId(evalInfo.getBetaSchemeId());
        userInfoBody.setEvaluationSchemeId(evalInfo.getEvaluationSchemeId());
        userInfoBody.setAgreementId(evalInfo.getAgreementId());
        userInfoBody.setSecretCmd(treadmillDeviceInfo.getSecretKey());

        // 发送用户信息
        TreadmillMsg treadmillMsg = TreadmillMsgFactory.build(MessageType.SET_USER_INFO,
                userInfoBody);
        boolean b = treadmillManager.sendMsg(treadmillMsg);
        if (!b) {
            Log.e(TAG, "startWarmUp: 发送用户信息到跑步机失败");
            ToastUtil.showMessage("发送用户信息到跑步机失败");
            return false;
        }

        // 发送开始指令
        CommandBody commandBody = new CommandBody();
        commandBody.setCommandId(CommandID.START.getId());
        treadmillMsg = TreadmillMsgFactory.build(MessageType.SET_COMMAND, commandBody);
        b = treadmillManager.sendMsg(treadmillMsg);
        if (!b) {
            Log.e(TAG, "startWarmUp: 发送跑步机开始指令失败");
            ToastUtil.showMessage("发送跑步机开始指令失败");
            return false;
        }

        // 开始热身指令
        StageBody stageBody = new StageBody();
        stageBody.setStageType(StageType.WARM_UP.getId());
        treadmillMsg = TreadmillMsgFactory.build(MessageType.SET_STAGE, stageBody);
        b = treadmillManager.sendMsg(treadmillMsg);
        if (!b) {
            Log.e(TAG, "startWarmUp: 发送跑步机开始指令失败");
            ToastUtil.showMessage("发送开始热身指令失败");
            return false;
        }

        return true;

    }

    /**
     * 开始测试
     *
     * @return
     */
    private boolean startTest() {
        // 开始热身指令
        StageBody stageBody = new StageBody();
        stageBody.setStageType(StageType.TESTING.getId());
        TreadmillMsg treadmillMsg = TreadmillMsgFactory.build(MessageType.SET_STAGE, stageBody);
        boolean b = treadmillManager.sendMsg(treadmillMsg);
        if (!b) {
            Log.e(TAG, "startTest: 发送开始测试指令失败");
            ToastUtil.showMessage("发送开始测试指令失败");
            return false;
        }

        return true;
    }

    /**
     * 开始恢复
     *
     * @return
     */
    private boolean startRecover() {
        // 开始热身指令
        StageBody stageBody = new StageBody();
        stageBody.setStageType(StageType.RECOVER.getId());
        TreadmillMsg treadmillMsg = TreadmillMsgFactory.build(MessageType.SET_STAGE, stageBody);
        boolean b = treadmillManager.sendMsg(treadmillMsg);
        if (!b) {
            Log.e(TAG, "startRecover: 发送开始恢复指令失败");
            ToastUtil.showMessage("发送开始恢复指令失败");
            return false;
        }

        return true;
    }

    /**
     * 获取协议详情
     *
     * @param agreementId
     */
    public void getAgreement(Long agreementId) {
        checkSource.getAgreement(agreementId, new Callback.CommonCallback<AgreementResponse>() {
            @Override
            public void onSuccess(AgreementResponse result) {
                agreementResponse = result;
                view.onAgreementResponse(agreementResponse);
            }

            @Override
            public void onError(Throwable e, String code, String message) {
                processError(e, code, message);
            }
        });
    }

    /**
     * 监听跑步机的数据
     */
    private TreadmillWebsocketManager.TreadmillDataLis treadmillDataLis =
            new TreadmillWebsocketManager.TreadmillDataLis() {
        @Override
        public void onTreadmillDataBody(TreadmillDataBody treadmillDataBody) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    view.onTreadmillDataBody(treadmillDataBody);
                }
            });
        }

        @Override
        public void onEcgBody(EcgBody ecgBody) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    view.onEcgBody(ecgBody);
                }
            });
        }

        @Override
        public void onHeartRateDataBody(HeartRateDataBody heartRateDataBody) {
            handler.post(new Runnable() {
                @Override
                public void run() {
                    view.onHeartRateDataBody(heartRateDataBody);
                }
            });
        }
    };

    @Override
    public BaseView getView() {
        return view;
    }
}
